package com.crm.im.core.filter;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.serialization.ClassResolver;
import io.netty.handler.codec.serialization.ObjectDecoder;

import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import sun.misc.BASE64Encoder;

import com.crm.im.core.constant.IMConstant;
import com.crm.im.core.model.SentBody;
/**
 *  服务端接收消息解码，可在此解密消息
 */
public class ServerMessageDecoder extends ObjectDecoder  {
	protected final Logger logger = Logger.getLogger(ServerMessageDecoder.class.getSimpleName());
	public ServerMessageDecoder(ClassResolver classResolver) {
		super(classResolver);
	}

	@Override
	public Object decode(ChannelHandlerContext arg0, ByteBuf  buffer) throws Exception   {
		
		final ByteBuf  tBuffer = PooledByteBufAllocator.DEFAULT.buffer(320);
		
		buffer.markReaderIndex();
		boolean complete = false;  
		
		while(buffer.isReadable()){
			byte b = buffer.readByte();
			if (b == IMConstant.MESSAGE_SEPARATE  || b == IMConstant.FLEX_DATA_SEPARATE) {
				complete = true;
				break;
			} else {
				tBuffer.writeByte(b);
			}
		}
		
		String message = new String(new String(ByteBufUtil.getBytes(tBuffer),IMConstant.UTF8));
		if(complete){
			
			
			logger.info(message);
			
			
			Object body = parserMessageToSentBody(message);
			return body;
			
		} /*else if(message.indexOf(IMConstant.WEBSOCKET_REWUEST)>-1){
			Object body = parserMessageToSentBody(message);
			return body;
		} */
		else{
		 
			buffer.resetReaderIndex();
			return null;
		}
		 
	}
	
	private Object  parserMessageToSentBody(String message) throws Exception
	{
		
		SentBody body = new SentBody();
		/*
		 * 如果是心跳响应，则让HeartbeatHandler去处理
		 */
		if(message.equalsIgnoreCase(IMConstant.CMD_HEARTBEAT_RESPONSE)){
		 
			body.setKey(IMConstant.RequestKey.CLIENT_HEARTBEAT);
			return body;
		}
		
		/*
		 * flex 客户端安全策略请求，需要返回特定报文
		 */
		if(IMConstant.FLEX_POLICY_REQUEST.equalsIgnoreCase(message)){
		
			body.setKey(IMConstant.RequestKey.CLIENT_FLASH_POLICY);
			return body;
		}
		
		/**
		 * websocket请求 
		 */
		 /*if(message.indexOf(IMConstant.WEBSOCKET_REWUEST)>-1){
			 
			String wsKey[] = message.split("Sec-WebSocket-Key:");
			if(wsKey.length>1){
				// CHROME WEBSOCKET VERSION 8中定义的GUID，详细文档地址：http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-10  
				String guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";  
				String subString[] = wsKey[1].split("\r\n");
				String key = subString[0];
				key += guid;  
			
				try {  
			           MessageDigest md = MessageDigest.getInstance("SHA-1");  
			           md.update(key.getBytes("UTF-8"), 0, key.length());  
			           byte[] sha1Hash = md.digest();  
			           key = base64Encode(sha1Hash);  
			       } catch (NoSuchAlgorithmException e) {  
			               logger.error("NoSuchAlgorithmException:" + e.getMessage(), e);  
			       } catch (UnsupportedEncodingException e) {  
			               logger.error("UnsupportedEncodingException:" + e.getMessage(), e);  
			       }  
				
			String xml="<?xml version=\"1.0\" encoding=\"UTF-8\"?><sent><key>"+IMConstant.RequestKey.CLIENT_WEBSOCKET_POLICY+"</key><data><deviceId><![CDATA["+key+"]]></deviceId></data></sent>";
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();   
	        DocumentBuilder builder = factory.newDocumentBuilder();  
	        Document doc = builder.parse(new ByteArrayInputStream(xml.getBytes()));
	        body.setKey(doc.getElementsByTagName("key").item(0).getTextContent());
	        NodeList dataNodeList = doc.getElementsByTagName("data");
	        if(dataNodeList!=null && dataNodeList.getLength()>0){
		        NodeList items = dataNodeList.item(0).getChildNodes();  
		        for (int i = 0; i < items.getLength(); i++) {  
		            Node node = items.item(i);  
		            body.getData().put(node.getNodeName(), node.getTextContent());
		        }
	        }
	        
			}
			return body;
		} */
		 
		 
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();   
        DocumentBuilder builder = factory.newDocumentBuilder();  
        Document doc = builder.parse(new ByteArrayInputStream(message.toString().getBytes(IMConstant.UTF8)));
        body.setKey(doc.getElementsByTagName("key").item(0).getTextContent());
        NodeList dataNodeList = doc.getElementsByTagName("data");
        if(dataNodeList!=null && dataNodeList.getLength()>0){
         
	        NodeList items = dataNodeList.item(0).getChildNodes();  
	        for (int i = 0; i < items.getLength(); i++) {  
	            Node node = items.item(i);  
	            body.getData().put(node.getNodeName(), node.getTextContent());
	        }
        }
        
        return body;
	}
	
	/** 
	    * 将输入字节数组进行base64编码，再返回编码后的字符串 
	    *  
	    * @param input 
	    * @return 
	    */  
	   public static String base64Encode(byte[] input) {  
	       BASE64Encoder encoder = new BASE64Encoder();  
	       String base64 = encoder.encode(input);  
	       return base64;  
	   }  

}
